package com.ruoyi.im.controller;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.im.entity.MsgRoute;
import com.ruoyi.im.entity.UserEntity;
import com.ruoyi.im.service.ImService;
import com.ruoyi.im.service.MsgService;
import com.ruoyi.im.service.OffLineMsgService;
import com.ruoyi.im.utils.RouteQueueUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@ServerEndpoint("/websocket/message/{userId}")
public class ServerEndPoint {

    private static final Logger LOGGER = LoggerFactory.getLogger(ServerEndPoint.class);
    /**
     * 在线的会话列表
     */
    public static Map<Integer, Session> onlineSessionList = new ConcurrentHashMap<>();

    private static RedisTemplate redisTemplate;
    private static OffLineMsgService offLineMsgService;
    private static ImService imService;
    private static RouteQueueUtil routeQueueUtil;
    private static MsgService msgService;

    @Autowired
    public void setOffLineMsgService(OffLineMsgService offLineMsgService) {
        ServerEndPoint.offLineMsgService = offLineMsgService;
    }

    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        ServerEndPoint.redisTemplate = redisTemplate;
    }

    @Autowired
    public void setImService(ImService imService) {
        ServerEndPoint.imService = imService;
    }

    @Autowired
    public void setRouteQueueUtil(RouteQueueUtil routeQueueUtil) {
        ServerEndPoint.routeQueueUtil = routeQueueUtil;
    }

    @Autowired
    public void setMsgService(MsgService msgService) {
        ServerEndPoint.msgService = msgService;
    }

    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Integer userId) throws Exception {
        //登录上线（保存当前用户对应的serverid）
        LOGGER.info("用户" + userId + "上线");
        ValueOperations<String, Object> vo = redisTemplate.opsForValue();
        vo.set("ws:session:cluster:id:" + userId, routeQueueUtil.getRouteKey());
        onlineSessionList.put(userId, session);
        //待发送消息写入到mq中
        List<Object> offlineMsg = offLineMsgService.getOfflineMsg(userId);
        if (offlineMsg != null && offlineMsg.size() > 0) {
            for (Object o : offlineMsg) {
                mqrouteMsg((MsgRoute) o);
            }
        }
    }

    @OnClose
    public void onClose(Session session) {

    }

    @OnError
    public void onError(Session session, Throwable exception) throws Exception {
        if (session.isOpen()) {
            // 关闭连接
            session.close();
        }
        exception.printStackTrace();

    }

    /**
     * 服务器接收到客户端消息时调用的方法
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        LOGGER.info("接收消息{}", message);
        MsgRoute msgRoute = JSON.parseObject(message, MsgRoute.class);
        mqrouteMsg(msgRoute);
    }

    private void mqrouteMsg(MsgRoute msgRoute) {
        Integer type = msgRoute.getType();
        if (type == 2) {
            msgToGroup(msgRoute);
            return;
        }
        //设置消息id
        msgRoute.setMsgId(msgService.geneMsgId(msgRoute.getReceiverId(), msgRoute.getSenderId()));
        routeQueueUtil.msgToPerson(msgRoute);
    }

    private void msgToGroup(MsgRoute msgRoute) {
        Integer groupId = msgRoute.getGroupId();
        //查询组里面的成员
        List<Object> groupList = imService.getGroupUserList(groupId);
        Integer integer = msgService.geneMsgGroupId(groupId);
        for (Object o : groupList) {
            UserEntity user = (UserEntity) o;
            Integer userId = user.getUserId();
            //群发 取组id
            msgRoute.setMsgId(integer);
            msgRoute.setReceiverId(userId);
            routeQueueUtil.msgToPerson(msgRoute);
        }
    }


}
